<?php

require_once( "TestHarness.php" );
/* ====================================================================
 *         Test Cases for Lifecycle
 * ====================================================================
 */

/**
 * This is sort of a complex setup, but what is happening is pretty simple. 
 * Basically there is a config file that sets up
 * 3 phase listeners (subclasses of TestPhaseListener, above). They resolve 
 * phaseTesterBean and increment counters. The test class also has a reference to that bean,
 * and it checks the counters.
 */
class PhpFaces_Test_Lifecycle_PhaseListenerTest extends PhpFaces_Test_AbstractPhpFacesTestCase {
	
	const PHASE_TESTER_EL = "#{phaseTesterBean}";
	
	protected $phaseTesterBean;
	
	public function getConfigPath() {
		return PhpFaces_TestDir."faces-config-lifecycle-test.xml";
	}
	
	public function setUp() {
		parent::setUp();
		$this->phaseTesterBean = $this->facesContext->resolve( self::PHASE_TESTER_EL );
	}
	
	public function testPhaseListenerHappyPath() {

		$lifecycleFactory = PhpFaces_LifecycleFactory::GetInstance();
		$lifecycle = $lifecycleFactory->getLifecycle( "default" );
/*
		$anyPhaseListener = new TestPhaseListener( PhpFaces_PhaseId::ANY_PHASE );
		$phase1Listener = new TestPhaseListener( PhpFaces_PhaseId::APPLY_REQUEST_VALUES );
		$renderResponseListener = new TestPhaseListener( PhpFaces_PhaseId::RENDER_RESPONSE );
		
		$lifecycle->addPhaseListener( $anyPhaseListener );
		$lifecycle->addPhaseListener( $phase1Listener );
		$lifecycle->addPhaseListener( $renderResponseListener );
*/

		$lifecycle->execute( $this->facesContext );
		
		$this->assertEquals( 5, $this->phaseTesterBean->getCounter( "TestPhaseListener_AnyPhase_before" ) );
		$this->assertEquals( 5, $this->phaseTesterBean->getCounter( "TestPhaseListener_AnyPhase_after" ) );
		
		$this->assertEquals( 1, $this->phaseTesterBean->getCounter( "TestPhaseListener_ApplyRequestValues_before" ) );
		$this->assertEquals( 1, $this->phaseTesterBean->getCounter( "TestPhaseListener_ApplyRequestValues_after" ) );
		/*
		$listener->render( $this->facesContext );
		
		$this->assertEquals( 6, $this->phaseTesterBean->getCounter( "TestPhaseListener_AnyPhase_before" ) );
		$this->assertEquals( 6, $this->phaseTesterBean->getCounter( "TestPhaseListener_AnyPhase_after" ) );
		
		$this->assertEquals( 1, $this->phaseTesterBean->getCounter( "TestPhaseListener_RenderResponse_before" ) );
		$this->assertEquals( 1, $this->phaseTesterBean->getCounter( "TestPhaseListener_RenderResponse_after" ) );
		*/
	}
}

/* ====================================================================
 *         Supporting Classes for Lifecycle
 * ====================================================================
 */

// ************************* testPhaseListener *************************

abstract class TestPhaseListener implements PhpFaces_Event_PhaseListener { 
	
	public $numberBeforePhase = 0;
	public $numberAfterPhase = 0;
	
	public function __construct() {
	}
	
	public function beforePhase( PhpFaces_Event_PhaseEvent $event ) {
			$event->getFacesContext()->resolve( PhpFaces_Test_Lifecycle_PhaseListenerTest::PHASE_TESTER_EL )->incrementCounter( get_class( $this ) . "_before" );
	}
	
	public function afterPhase( PhpFaces_Event_PhaseEvent $event ) {
		$event->getFacesContext()->resolve( PhpFaces_Test_Lifecycle_PhaseListenerTest::PHASE_TESTER_EL )->incrementCounter( get_class( $this ) . "_after" );
	}
}

class TestPhaseListener_AnyPhase extends TestPhaseListener {
	public function getPhaseId() {
		return PhpFaces_PhaseId::ANY_PHASE;
	}
}

class TestPhaseListener_ApplyRequestValues extends TestPhaseListener {
	public function getPhaseId() {
		return PhpFaces_PhaseId::APPLY_REQUEST_VALUES;
	}
}

class TestPhaseListener_RenderResponse extends TestPhaseListener {
	public function getPhaseId() {
		return PhpFaces_PhaseId::RENDER_RESPONSE;
	}
}


class PhaseTesterBean {
	
	public $counters;
	
	public function __construct() {
		$this->counters = array();
	}
	
	public function incrementCounter( $name ) {
		if( !$this->counterExists( $name ) ) {
			$this->counters[ $name ] = 1;
		} else {
			$this->counters[ $name ]++;
		}
	}
	
	public function getCounter( $name ) {
		return $this->counterExists( $name ) ? $this->counters[ $name ] : null;
	}
	
	public function counterExists( $name ) {
		return isset( $this->counters[$name] );
	}
}

?>